package com.jlboot.config;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.config.SaCookieConfig;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.context.SaTokenContext;
import cn.dev33.satoken.jfinal.SaTokenActionHandler;
import cn.dev33.satoken.jfinal.SaTokenContextForJfinal;
import cn.dev33.satoken.util.SaTokenConsts;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.*;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.plugin.druid.IDruidStatViewAuth;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.plugin.redis.RedisPlugin;
import com.jfinal.render.ViewType;
import com.jfinal.template.Engine;
import com.jlboot.app.admin.controller.test.model.TestDemo;
import com.jlboot.app.admin.controller.test.model.TestTable;
import com.jlboot.core.ConfigUtil;
import com.jlboot.core.Interceptor.GlobalInterceptor;
import com.jlboot.core.base.JfinalCheck;
import com.jlboot.core.consts.Consts;
import com.jlboot.core.exception.JlServerException;
import com.jlboot.core.handler.GlobalHandler;
import com.jlboot.core.plugins.sms.model.SysVcode;
import com.jlboot.model.po.sys.*;
import com.jlboot.model.po.weixin.WxMember;
import com.jlboot.model.po.weixin.WxMessage;
import com.jlboot.model.po.weixin.WxPay;
import com.jlboot.model.po.weixin.WxTemplet;
import com.jlboot.app.admin.router.AdminRoutes;
import com.jlboot.app.openapi.router.OpenApiRoutes;
import com.jlboot.app.common.router.CommonRoutes;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;


/**
 * Created by 51594 on 2022/7/27.
 */
@Slf4j
public class AppConfig extends JFinalConfig {

    /**
     * 默认配置对象
     */
    private static Prop pu;

    static void loadConfig(){
        try {
            if (pu == null) {
                pu = PropKit.useFirstFound("config-pro.txt", "config-dev.txt");
            }
        } catch (Exception e) {
            throw new JlServerException("文件加载异常",e);
        }
    }

    public AppConfig() {
        //注册权限验证功能，由saToken处理请求上下文
        SaTokenContext saTokenContext = new SaTokenContextForJfinal();
        SaManager.setSaTokenContext(saTokenContext);
        //加载权限角色设置数据接口
        SaManager.setStpInterface(new StpInterfaceImpl());
        //设置token生成类型
        SaTokenConfig saTokenConfig = new SaTokenConfig();
        saTokenConfig.setTokenStyle(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID);
        saTokenConfig.setTimeout(60*60*24*7);  //登录有效时间4小时
        saTokenConfig.setActiveTimeout(-1); //半小时无操作就冻结 token
        saTokenConfig.setIsShare(false);
        saTokenConfig.setTokenName(Consts.TOKEN_NAME);    //更改satoken的cookies名称
        //saTokenConfig.setTokenPrefix(Consts.TOKEN_NAME_PREFIX);
        SaCookieConfig saCookieConfig = new SaCookieConfig();
        saCookieConfig.setHttpOnly(true);   //开启cookies 的httponly属性
        saTokenConfig.setCookie(saCookieConfig);

        SaManager.setConfig(saTokenConfig);
    }

    /**
     * 最先执行
     * action 1
     *
     * @param con
     */
    public void configConstant(Constants con) {

        loadConfig();

        //检查配置文件是否存在
        JfinalCheck.checkConfig();
        //jfinal设置使用slf4j
        con.setToSlf4jLogFactory();

        //开启开发模式
        con.setDevMode(ConfigUtil.DEBUG());
        //配置视图类型，默认使用 jfinal enjoy 模板引擎
        con.setViewType(ViewType.JFINAL_TEMPLATE);
        con.setEncoding("UTF8");
        con.setJsonDatePattern("yyyy-MM-dd HH:mm");

        // 开启对 jfinal web 项目组件 Controller、Interceptor、Validator 的注入
        con.setInjectDependency(true);
        // 开启对超类的注入。不开启时可以在超类中通过 Aop.get(...) 进行注入
        con.setInjectSuperClass(true);

        con.setError404View("/WEB-INF/resource/pages/error/404.html");
        con.setError500View("/WEB-INF/resource/pages/error/500.html");
        con.setErrorView(400, "/WEB-INF/resource/pages/error/400.html");
    }

    /**
     * 3
     * 配置路由
     *
     * @param routes
     */
    public void configRoute(Routes routes) {

        routes.add(new AdminRoutes());
        routes.add(new OpenApiRoutes());
        routes.add(new CommonRoutes());


    }

    /**
     * 5
     *
     * @param engine
     */
    public void configEngine(Engine engine) {
        engine.setDevMode(true);

        String ctx_path=ConfigUtil.getWebPath();
        String ctx_admin_path=ConfigUtil.getWebPath() + ConfigUtil.getWebAdminPath();

        engine.addSharedObject("ctx_path", ctx_path);
        engine.addSharedObject("ctx_admin_path", ctx_admin_path);

    }

    /**
     * 4
     *
     * @param me
     */
    public void configPlugin(Plugins me) {
        // database config
        String MYSQL_URL = ConfigUtil.getProperty("MYSQL_URL");
        String MYSQL_USERNAME = ConfigUtil.getProperty("MYSQL_USERNAME");
        String MYSQL_PWD = ConfigUtil.getProperty("MYSQL_PWD");
        DruidPlugin dp = new DruidPlugin(MYSQL_URL, MYSQL_USERNAME, MYSQL_PWD);
        /////////////////////////////////
        dp.addFilter(new StatFilter()); //sql监控
        dp.addFilter(new WallFilter()); //防止sql注入
        dp.setValidationQueryTimeout(2);//默认的健康检查超时时间
        WallFilter wall = new WallFilter();
        wall.setDbType("mysql"); //mysql
        dp.addFilter(wall);
        //////////////////////////////////////////////
        me.add(dp);
        ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
        me.add(arp);
//        /////////////////////////定时任务/////////////////////////////
        // if (ConfigUtil.isLinux()) {
        //me.add(MyCron4jPlugin.n());
        //  }
        /////////////////////////////redis///////////////////////////////////
        RedisPlugin rp = new RedisPlugin("demo", "demo", 6379, 10000, "testabc");

        me.add(rp);
        //////////////////////////////////////////////////////////////////////////////////
//        /////////////////////////cache/////////////////////////////
        me.add(new EhCachePlugin());
        /////////////////////////系统表/////////////////////////////
        arp.addMapping("sys_menu", "id", SysMenu.class);
        arp.addMapping("sys_user", "id", SysUser.class);
        arp.addMapping("sys_role", "id", SysRole.class);
        arp.addMapping("sys_type", "id", SysType.class);
        arp.addMapping("sys_type_detail", "id", SysTypeDetail.class);
        arp.addMapping("sys_dept", "id", SysDept.class);
        arp.addMapping("sys_work_log", "id", SysWorkLog.class);
        arp.addMapping("sys_config", "id", SysConfig.class);
        arp.addMapping("sys_code", "id", SysCode.class);
        arp.addMapping("sys_code_column", "id", SysCodeColumn.class);
        arp.addMapping("sys_files", "id", SysFile.class);
        arp.addMapping("sys_data", "id", SysData.class);
        arp.addMapping("sys_online","id", SysOnline.class);
        arp.addMapping("sys_ip", "id", SysIp.class);
        arp.addMapping("sys_task", "id", SysTask.class);
        arp.addMapping("sys_activity", "id", SysActivity.class);
        arp.addMapping("sys_vcode", "id", SysVcode.class);
        arp.addMapping("sys_post", "id", SysPost.class);
        arp.addMapping("sys_app", "id", SysApp.class);

        arp.addMapping("test_table", "id", TestTable.class);
        arp.addMapping("test_table", "id", TestDemo.class);
//        /////////////////////////微信/////////////////////////////
        arp.addMapping("wx_member", "id", WxMember.class);
        arp.addMapping("wx_message", "id", WxMessage.class);
        arp.addMapping("wx_pay", "id", WxPay.class);
        arp.addMapping("wx_templet", "id", WxTemplet.class);


    }

    /**
     * 2
     *
     * @param interceptors
     */
    public void configInterceptor(Interceptors interceptors) {

        interceptors.addGlobalActionInterceptor(new GlobalInterceptor());

    }

    /**
     * 6
     *
     * @param handlers
     */
    public void configHandler(Handlers handlers) {

        //将上下文交给Satoken处理
        handlers.setActionHandler(new SaTokenActionHandler());

        //全局Handler
        handlers.add(new GlobalHandler());

        /////////////////////////druid配置////////////////////////////////////////////
        DruidStatViewHandler dvh = new DruidStatViewHandler("/admin9527/druid", new IDruidStatViewAuth() {
            public boolean isPermitted(HttpServletRequest request) {
                return true;
            }
        });

        handlers.add(dvh);
        ///////////////////////////////////////////////////////////////////////
    }


    /**
     * 7
     * 统启动完成后回调
     */

    public void onStart() {
        //加载数据库配置的定时任务
        SysTask.dao.initAllTask();
        System.out.println("-----------------定时任务启动成功------------------");

        System.out.println("-----------------启动成功------------------");
    }

    /**
     * 8
     * 系统关闭之前回调
     */

    public void onStop() {
        //关闭系统时，需要同步日志写入
        SysWorkLog.dao.scyWorkLog();
        SysTask.dao.closeAllTask();
        //  System.out.println("-------------end----------------------");
    }


}
